﻿// <copyright file="EntityFrameworkClassesTemplate.cs" company="T4 Toolbox Team">
//  Copyright © T4 Toolbox Team. All Rights Reserved.
// </copyright>

namespace T4Toolbox.EntityFramework
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity.Design;
    using System.Data.Metadata.Edm;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;
    using System.Xml;

    /// <summary>
    /// Generates Entity Framework classes.
    /// </summary>
    public class EntityFrameworkClassesTemplate : Template
    {
        /// <summary>
        /// Gets or sets the conceptual model for which classes need to be generated.
        /// </summary>
        /// <value>
        /// Conceptual model XML.
        /// </value>
        public string ConceptualModel { get; set; }

        /// <summary>
        /// Gets or sets the programming language for generating entity classes.
        /// </summary>
        /// <value>
        /// A <see cref="LanguageOption"/> value, 
        /// <see cref="System.Data.Entity.Design.LanguageOption.GenerateCSharpCode"/> or
        /// <see cref="System.Data.Entity.Design.LanguageOption.GenerateVBCode"/>.
        /// </value>
        public LanguageOption LanguageOption { get; set; }

        /// <summary>
        /// Generates Entity Framework classes.
        /// </summary>
        /// <returns>
        /// Generated classes.
        /// </returns>
        [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "stringReader is not closed by xmlReader")]
        public override string TransformText()
        {
            using (StringReader stringReader = new StringReader(this.ConceptualModel))
            using (XmlReader xmlReader = XmlReader.Create(stringReader, new XmlReaderSettings() { CloseInput = false }))
            using (StringWriter stringWriter = new StringWriter(this.GenerationEnvironment, CultureInfo.CurrentCulture))
            {
#if DEV10
                EntityCodeGenerator generator = new EntityCodeGenerator(this.LanguageOption);
#else
                EntityClassGenerator generator = new EntityClassGenerator(this.LanguageOption);
#endif
                IEnumerable<EdmSchemaError> errors = generator.GenerateCode(xmlReader, stringWriter);
                EntityFrameworkGenerator.HandleErrors(errors, this.Errors);
                return this.GenerationEnvironment.ToString();
            }
        }

        /// <summary>
        /// Validates properties before code generation.
        /// </summary>
        protected override void Validate()
        {
            if (string.IsNullOrEmpty(this.ConceptualModel))
            {
                throw new TransformationException("ConceptualModel property must be assigned");
            }
        }
    }
}
